from flask import Blueprint, request, jsonify
from werkzeug.security import check_password_hash
from flask_jwt_extended import create_access_token, jwt_required, get_jwt_identity, unset_jwt_cookies
from .models import db, User
import logging

logger = logging.getLogger(__name__)
auth = Blueprint('auth', __name__)

@auth.route('/register', methods=['POST'])
def register():
    """用户注册"""
    print("============= REGISTER API CALLED =============")
    print(f"Request Content-Type: {request.headers.get('Content-Type')}")
    
    # 确保能接收到JSON数据
    if not request.is_json:
        print("ERROR: Request is not JSON")
        return jsonify({"error": "预期JSON格式的请求"}), 400
        
    try:
        data = request.json
        print(f"Received data: {data}")
        
        username = data.get('username')
        password = data.get('password')
        email = data.get('email')
        
        print(f"Username: {username}, Email: {email}")
        
        if not username or not password:
            print("ERROR: Missing username or password")
            return jsonify({'error': '用户名和密码不能为空'}), 400

        # 检查用户是否存在
        existing_user = User.query.filter_by(username=username).first()
        if existing_user:
            print(f"ERROR: Username {username} already exists")
            return jsonify({'error': '用户名已存在'}), 409
        
        if email:
            existing_email = User.query.filter_by(email=email).first()
            if existing_email:
                print(f"ERROR: Email {email} already registered")
                return jsonify({'error': '邮箱已被注册'}), 409

        # 创建新用户
        print("Creating new user...")
        new_user = User(username=username, email=email)
        new_user.set_password(password)
        
        try:
            print("Adding user to database...")
            db.session.add(new_user)
            db.session.commit()
            print(f"User {username} registered successfully")
            
            # 生成token - 使用用户的 id
            print("Generating access token...")
            access_token = create_access_token(identity=str(new_user.id))  # 转换为字符串
            
            print("Registration successful, returning response")
            return jsonify({
                'message': '注册成功', 
                'access_token': access_token,
                'user': new_user.to_dict(include_email=True)
            }), 201
            
        except Exception as e:
            db.session.rollback()
            print(f"ERROR during database operation: {str(e)}")
            print(f"Error type: {type(e)}")
            import traceback
            print(traceback.format_exc())  # 打印完整的堆栈跟踪
            logger.error(f"Error registering user {username}: {e}")
            return jsonify({'error': f'注册失败: {str(e)}'}), 500
            
    except Exception as e:
        print(f"CRITICAL ERROR in register function: {str(e)}")
        print(f"Error type: {type(e)}")
        import traceback
        print(traceback.format_exc())  # 打印完整的堆栈跟踪
        return jsonify({'error': f'处理请求时发生错误: {str(e)}'}), 500

@auth.route('/login', methods=['POST'])
def login():
    """用户登录"""
    data = request.json
    username = data.get('username')
    password = data.get('password')

    if not username or not password:
        return jsonify({'error': '用户名和密码不能为空'}), 400

    user = User.query.filter_by(username=username).first()

    if user and user.check_password(password):
        # 生成token - 使用用户的 id
        access_token = create_access_token(identity=str(user.id))  # 转换为字符串
        logger.info(f"User {username} logged in successfully.")
        return jsonify({
            'access_token': access_token,
            'user': user.to_dict(include_email=True)
        }), 200
    else:
        logger.warning(f"Failed login attempt for user {username}.")
        return jsonify({'error': '用户名或密码错误'}), 401

@auth.route('/logout', methods=['POST'])
@jwt_required() # 需要登录才能登出
def logout():
    """用户登出"""
    # 对于JWT，登出通常在客户端删除token即可。
    # 如果需要服务器端强制失效，需要实现token黑名单机制（更复杂）。
    # 这里我们返回一个消息，并可以清除客户端可能设置的cookie（如果使用cookie存储token）
    response = jsonify({'message': '登出成功'})
    # unset_jwt_cookies(response) # 如果使用cookie存储token，取消注释此行
    current_user_id = get_jwt_identity()
    user = User.query.get(current_user_id)
    if user:
        logger.info(f"User {user.username} logged out.")
    return response

@auth.route('/status', methods=['GET'])
@jwt_required(optional=True) # 允许未登录访问，但如果登录了可以获取信息
def status():
    """检查用户登录状态"""
    current_user_id = get_jwt_identity()
    if current_user_id:
        user = User.query.get(current_user_id)
        if user:
            return jsonify({
                'logged_in': True,
                'user': user.to_dict(include_email=True)
            })
    return jsonify({'logged_in': False, 'user': None})

# 可以添加更多接口，如获取/更新用户信息、修改密码等
@auth.route('/profile', methods=['GET'])
@jwt_required()
def get_profile():
    """获取当前用户信息"""
    current_user_id = get_jwt_identity()
    user = User.query.get(current_user_id)
    if user:
        return jsonify(user.to_dict(include_email=True))
    return jsonify({'error': '用户不存在'}), 404

@auth.route('/profile', methods=['PUT'])
@jwt_required()
def update_profile():
    """更新用户信息"""
    current_user_id = get_jwt_identity()
    user = User.query.get(current_user_id)
    if not user:
        return jsonify({'error': '用户不存在'}), 404

    data = request.json
    # 更新允许修改的字段
    if 'email' in data:
        # 检查邮箱是否已被其他用户使用
        existing_user = User.query.filter(User.email == data['email'], User.id != current_user_id).first()
        if existing_user:
            return jsonify({'error': '邮箱已被注册'}), 409
        user.email = data['email']
    if 'avatar_url' in data:
        user.avatar_url = data['avatar_url']
    if 'bio' in data:
        user.bio = data['bio']
    if 'profile_info' in data:
        user.profile_info = data['profile_info'] # 允许更新预留的JSON信息

    try:
        db.session.commit()
        logger.info(f"User {user.username} profile updated.")
        return jsonify({'message': '用户信息更新成功', 'user': user.to_dict(include_email=True)})
    except Exception as e:
        db.session.rollback()
        logger.error(f"Error updating profile for user {user.username}: {e}")
        return jsonify({'error': '更新失败，请稍后重试'}), 500